#ifndef DW_BASE_ASSERT_H
#	define DW_BASE_ASSERT_H

#ifdef DW_USE_ASSERTION
#include <windows.h>

//! @todo Make dwAssert a variadic macro #define dwAssert(expr, ...) if (!(x)) { printf(__VA_ARGS__); }

#define dwAssert(expr, msg) \
	do \
	{ \
		if (!(expr)) \
		{ \
			switch (::MessageBox(NULL, "Message: " msg "\nExpression: '" dwQuote(expr) "'\nFile: " __FILE__, "Assertion failed!", MB_ABORTRETRYIGNORE | MB_ICONEXCLAMATION)) \
			{ \
			case IDABORT: \
				::exit(-1); \
				break ; \
			case IDRETRY: \
				dwBreak(); \
				break ; \
			case IDIGNORE: \
				break ; \
			} \
		} \
	} \
	while(0)

#else // !DW_USE_ASSERT
#	define dwAssert(expr, msg) ((void)0)
#endif // DW_USE_ASSERT

#define dwFail(msg) dwAssert(false, msg)

// Compile time assertion

namespace dw {

template < bool condition, typename StaticAssertMessage >
struct StaticAssertFail;

template < typename StaticAssertMessage >
struct StaticAssertFail< true, StaticAssertMessage > { enum { value = 1 }; };

template< int x >
struct StaticAssertTest {};

} // namespace dw

#define dwStaticAssert(condition, message) \
	typedef ::dw::StaticAssertTest< sizeof (::dw::StaticAssertFail< condition, class message >) > dwStaticAssertFailed##message

#define dwStaticAssertNoMsg(condition) dwStaticAssert(condition, No_message_provided)

#endif // !DW_BASE_ASSERT_H
